#include "STC12C2052AD.h"
#include  "intrins.h" //nop()
typedef unsigned char   uchar;  //1个字节类型
int width=50;  //pwm占空比
uchar adc_result=0;
uchar adc_result_last = 0;
uchar target = 0x5F;  //目标高度
int sum_result = 0;
double kp=4.4;   //比例系数
double kd=13.2;   //微分系数
sbit HE  =  P1^0;         //霍尔
sbit IN1 =  P3^4;
sbit IN2 =  P3^5;

#define ADC_FLAG  0x10
#define ADC_START 0x08
void delay(unsigned int x);
void init_pwm();
//void init_uart();
void init_adc();
void start_adc();
void setp(uchar p); //1为正，0为负
void send_uart(char *send);
void send_uart(uchar send);

void main()
{
    uchar a=0;
    setp(1);
    init_pwm();
    //init_uart();
    
    while(1)
    {
    for(a=0;a<4;a++)
    {
      init_adc();
      start_adc();
      sum_result+=adc_result;
    }
    sum_result /= 4;
     
    width=(int)kp*(target-sum_result)+kd*(adc_result_last-sum_result);
    if(width<=0)
    {
      setp(0);
      width = -width;
    }
    else
    {
      setp(1);
    }
    if(width>254)
        width = 254;
    if(width<5)
        width = 1;
    CCAP0H=CCAP0L=width;
    //delay(10000);
    //send_uart(adc_result);
    //send_uart(0xFF);
    //send_uart(width);
    adc_result_last = sum_result;
    adc_result = 0;
    sum_result =0;
    }
}

void init_adc()
{

    P1 = P1M0 = P1M1 = 0xff;  //P1设置悬空输入
    ADC_CONTR=0xE2; //打开adc电源，540时钟周期转换一次，P1.2作为ad输入
    _nop_();
    _nop_();
    _nop_();
    _nop_();  //datasheet要求延时四个时钟周期保证寄存器被置位
    
}
void init_pwm()
{
    CMOD = 0x02;  //PCA工作在SYSclk/2的频率上
    CCAPM0 = 0x42; //PWM0使能
    CL=0;
    CH=0;
    CCAP0H=CCAP0L=width;
    CR=1;
}

void init_uart()
{
    SM0 = 0;
    SM1 = 1;  //work in method 1
    REN = 0;  //ban receive uart_data
    TMOD = 0x20; 
    TH1=TL1=0xF3;
    TR1 = 1;
}
/*
void send_uart(char *send)
{
    unsigned int l=0;
    while(*(send+l))
    {
      SBUF = *(send+l);
      while(!TI);
      TI = 0;
      l++;
    }
}*/
void send_uart(uchar send)
{
    SBUF = send;
    while(!TI);
    TI = 0;
}


void start_adc()
{
    ADC_CONTR |= ADC_START;
    ADC_CONTR|=0x08;
    while(!(ADC_CONTR&ADC_FLAG));
    ADC_CONTR &=!ADC_FLAG;
    adc_result = ADC_DATA;
    ADC_DATA = 0;
}

void setp(uchar p)
{
    if(p)
    {
        IN1 = 0;
        IN2 = 1;
    }
    else
    {
       IN1 = 1;
       IN2 = 0; 
    }
}

void delay(unsigned int x)    //延时 x ms
{
    unsigned int i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}